/**
 * ***************************************************************************** Copyright (c) 2000,
 * 2009 IBM Corporation and others. All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0 which accompanies this
 * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html
 *
 * <p>Contributors: IBM Corporation - initial API and implementation
 * *****************************************************************************
 */
package org.eclipse.core.resources;

import java.util.EventListener;
import org.eclipse.core.runtime.CoreException;

/**
 * A participant in the saving of the workspace.
 *
 * <p>Plug-ins implement this interface and register to participate in workspace save operations.
 *
 * <p>Clients may implement this interface.
 *
 * @see IWorkspace#save(boolean, org.eclipse.core.runtime.IProgressMonitor)
 */
public interface ISaveParticipant extends EventListener {
  /**
   * Tells this participant that the workspace save operation is now complete and it is free to go
   * about its normal business. Exceptions are not expected to be thrown at this point, so they
   * should be handled internally.
   *
   * <p>Note: This method is called by the platform; it is not intended to be called directly by
   * clients.
   *
   * @param context the save context object
   */
  public void doneSaving(ISaveContext context);

  /**
   * Tells this participant that the workspace is about to be saved. In preparation, the participant
   * is expected to suspend its normal operation until further notice. <code>saving</code> will be
   * next, followed by either <code>doneSaving</code> or <code>rollback</code> depending on whether
   * the workspace save was successful.
   *
   * <p>Note: This method is called by the platform; it is not intended to be called directly by
   * clients.
   *
   * @param context the save context object
   * @exception CoreException if this method fails to snapshot the state of this workspace
   */
  public void prepareToSave(ISaveContext context) throws CoreException;

  /**
   * Tells this participant to rollback its important state. The context's previous state number
   * indicates what it was prior to the failed save. Exceptions are not expected to be thrown at
   * this point, so they should be handled internally.
   *
   * <p>Note: This method is called by the platform; it is not intended to be called directly by
   * clients.
   *
   * @param context the save context object
   * @see ISaveContext#getPreviousSaveNumber()
   */
  public void rollback(ISaveContext context);

  /**
   * Tells this participant to save its important state because the workspace is being saved, as
   * described in the supplied save context.
   *
   * <p>Note: This method is called by the platform; it is not intended to be called directly by
   * clients.
   *
   * <p>The basic contract for this method is the same for full saves, snapshots and project saves:
   * the participant must absolutely guarantee that any important user data it has gathered will not
   * be irrecoverably lost in the event of a crash. The only difference is in the space-time
   * tradeoffs that the participant should make.
   *
   * <ul>
   *   <li>Full saves: the participant is encouraged to save additional non-essential information
   *       that will aid it in retaining user state and configuration information and quickly
   *       getting back in sync with the state of the platform at a later point.
   *   <li>Snapshots: the participant is discouraged from saving non-essential information that
   *       could be recomputed in the unlikely event of a crash. This lifecycle event will happen
   *       often and participant actions should take an absolute minimum of time.
   *   <li>Project saves: the participant should only save project related data. It is discouraged
   *       from saving non-essential information that could be recomputed in the unlikely event of a
   *       crash.
   * </ul>
   *
   * For instance, the Java IDE gathers various user preferences and would want to make sure that
   * the current settings are safe and sound after a <code>save</code> (if not saved immediately).
   * The Java IDE would likely save computed image builder state on full saves, because this would
   * allow the Java IDE to be restarted later and not have to recompile the world at that time. On
   * the other hand, the Java IDE would not save the image builder state on a snapshot because that
   * information is non-essential; in the unlikely event of a crash, the image should be rebuilt
   * either from scratch or from the last saved state.
   *
   * <p>The following snippet shows how a plug-in participant would write its important state to a
   * file whose name is based on the save number for this save operation.
   *
   * <pre>
   *     Plugin plugin = ...; // known
   *     int saveNumber = context.getSaveNumber();
   *     String saveFileName = "save-" + Integer.toString(saveNumber);
   *     File f = plugin.getStateLocation().append(saveFileName).toFile();
   *     plugin.writeImportantState(f);
   *     context.map(new Path("save"), new Path(saveFileName));
   *     context.needSaveNumber();
   *     context.needDelta(); // optional
   * </pre>
   *
   * When the plug-in is reactivated in a subsequent workspace session, it needs to re-register to
   * participate in workspace saves. When it does so, it is handed back key information about what
   * state it had last saved. If it's interested, it can also ask for a resource delta describing
   * all resource changes that have happened since then, if this information is still available. The
   * following snippet shows what a participant plug-in would need to do if and when it is
   * reactivated:
   *
   * <pre>
   *     IWorkspace ws = ...; // known
   *     Plugin plugin = ...; // known
   *     ISaveParticipant saver = ...; // known
   *     ISavedState ss = ws.addSaveParticipant(plugin, saver);
   *     if (ss == null) {
   *         // activate for very first time
   *         plugin.buildState();
   *     } else {
   *         String saveFileName = ss.lookup(new Path("save"));
   *         File f = plugin.getStateLocation().append(saveFileName).toFile();
   *         plugin.readImportantState(f);
   *         IResourceChangeListener listener = new IResourceChangeListener() {
   *             public void resourceChanged(IResourceChangeEvent event) {
   *                 IResourceDelta delta = event.getDelta();
   *                 if (delta != null) {
   *                     // fast reactivation using delta
   *                     plugin.updateState(delta);
   *                 } else {
   *                     // slower reactivation without benefit of delta
   *                     plugin.rebuildState();
   *                 }
   *         };
   *         ss.processResourceChangeEvents(listener);
   *     }
   * </pre>
   *
   * @param context the save context object
   * @exception CoreException if this method fails
   * @see ISaveContext#getSaveNumber()
   */
  public void saving(ISaveContext context) throws CoreException;
}
